package com.ssh.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;

import com.ssh.dao.IBaseDao;

public abstract class BaseDaoImpl<T> implements IBaseDao<T> {

    @Resource(name = "sessionFactory")
    protected SessionFactory sessionFactory;
    
    // 维护的字节码对象
    private Class<T> clazz; // 要使用泛型，否则下面的方法无法返回泛型类型
    
    public BaseDaoImpl() {
        // 给clazz赋值
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        clazz = (Class) pt.getActualTypeArguments()[0];
    }

    @Override
    public void add(T t) {
        sessionFactory.getCurrentSession().save(t);
    }

    @Override
    public void delete(T t) {
        sessionFactory.getCurrentSession().delete(t);
    }

    @Override
    public void update(T t) {
        sessionFactory.getCurrentSession().update(t);
    }

    @Override
    public T findById(Serializable id) {
        return sessionFactory.getCurrentSession().load(clazz, id);
    }

    @Override
    public List<T> findAll() {
        Session session = sessionFactory.getCurrentSession();
        return session.createQuery("from " + clazz.getName(), clazz).list();
    }

	@Override
	public List<T> findByConditions(Map<String, Object> conditions) {
		// 进行实现。就是字符串的拼接
        StringBuffer sb = new StringBuffer();
        // 1. 先确定查询的表
        sb.append("from " + clazz.getName());
        sb.append(" where 1=1 ");
        // 2. 循环Map，拼接where中的条件。例如pid=:pid等。
        for (Map.Entry<String, Object> entry : conditions.entrySet()) {
            sb.append(" and " + entry.getKey() + "=:" + entry.getKey());
        }
        // 3. 得到Query
        Session session = sessionFactory.getCurrentSession();
        Query query = session.createQuery(sb.toString());
        // 4. 再遍历Map，设置预编译参数值
        for (Map.Entry<String, Object> entry : conditions.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        // 5. 返回查询集合即可
        return query.list();
	}
}
